package cn.hpclub.server.controller.admin;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSException;
import com.jfinal.upload.UploadFile;
import com.oreilly.servlet.multipart.FilePart;

import cn.hpclub.server.bean.SystemConfig;
import cn.hpclub.server.model.Admin;
import cn.hpclub.server.util.ImageUtil;
import cn.hpclub.server.util.OssUtils;
import cn.hpclub.server.util.OssUtils.UploadResult;
import cn.hpclub.server.util.UploadFileUtil;

/**
 * 后台Action类 - 文件上传
 * 
 */
public class UploadController extends BaseAdminController<Admin>{
    private static final String VERIFY_FAILED_MSG = "上传失败,后端MD5校验错误!";
    private static Logger       log               = LoggerFactory.getLogger(UploadController.class);

    // 获取上传进度
    public void progress(){
        Object prc = getSessionAttr("progress");
        if(prc == null){
            prc = 0;
        }
        renderJson(prc);
    }

    // 图片文件上传
    public void image(){
        String uploadFileName = "";
        File upload = null;
        FilePart.progresss.set(new FilePart.Progress(){

            public void progress(long currentSize){
                int totalsize = getRequest().getContentLength();
                double csize = (double)currentSize;
                double s = csize / totalsize * 100;
                setSessionAttr("progress", String.format("%.2f", s));
            }

            public void start(){
                setSessionAttr("progress", "0");
            }

            public void complate(){
                FilePart.progresss.remove();
                setSessionAttr("progress", "100");
            }

        });
        UploadFile imgageFile = getFile();
        if(imgageFile != null){
            upload = imgageFile.getFile();
            uploadFileName = imgageFile.getFileName();
        }
        if(upload == null){
            ajaxJsonErrorMessage("请选择上传文件!");
            return;
        }
        String allowedUploadImageExtension = getSystemConfig().getAllowedUploadImageExtension().toLowerCase();
        if(StringUtils.isEmpty(allowedUploadImageExtension)){
            ajaxJsonErrorMessage("不允许上传图片文件!");
            return;
        }
        String imageExtension = StringUtils.substringAfterLast(uploadFileName, ".").toLowerCase();
        String[] imageExtensionArray = allowedUploadImageExtension.split(SystemConfig.EXTENSION_SEPARATOR);
        if(!ArrayUtils.contains(imageExtensionArray, imageExtension)){
            ajaxJsonErrorMessage("只允许上传图片文件类型: " + allowedUploadImageExtension + "!");
            return;
        }
        int uploadLimit = getSystemConfig().getUploadLimit() * 1024;
        if(uploadLimit != 0){
            if(upload != null && upload.length() > uploadLimit){
                ajaxJsonErrorMessage("文件大小超出限制!");
                return;
            }
        }

        Map<String, Long> imgDetailMap = ImageUtil.getImageSize(upload);

        String uploadImagePath = UploadFileUtil.saveImage(upload);
        Map<String, String> jsonMap = new HashMap<String, String>();

        jsonMap.put(STATUS, SUCCESS);
        jsonMap.put("url", uploadImagePath);
        jsonMap.put("imgWidth", imgDetailMap.get("imgWidth").toString());
        jsonMap.put("imgHeight", imgDetailMap.get("imgHeight").toString());
        jsonMap.put("imgSize", imgDetailMap.get("imgSize").toString());
        renderJson(jsonMap);
    }

    // 其它文件上传
    public void file(){
        String uploadFileName = "";
        File upload = null;
        UploadFile upfile = getFile();
        if(upfile != null){
            upload = upfile.getFile();
            uploadFileName = upfile.getFileName();
        }
        if(upload == null){
            ajaxJsonErrorMessage("请选择上传文件!");
            return;
        }
        String allowedUploadFileExtension = getSystemConfig().getAllowedUploadFileExtension().toLowerCase();
        if(StringUtils.isEmpty(allowedUploadFileExtension)){
            ajaxJsonErrorMessage("不允许上传文件!");
            return;
        }
        String fileExtension = StringUtils.substringAfterLast(uploadFileName, ".").toLowerCase();
        String[] fileExtensionArray = allowedUploadFileExtension.split(SystemConfig.EXTENSION_SEPARATOR);
        if(!ArrayUtils.contains(fileExtensionArray, fileExtension)){
            ajaxJsonErrorMessage("只允许上传文件类型: " + allowedUploadFileExtension + "!");
            return;
        }
        int uploadLimit = getSystemConfig().getUploadLimit() * 1024;
        if(uploadLimit != 0){
            if(upload != null && upload.length() > uploadLimit){
                ajaxJsonErrorMessage("文件大小超出限制!");
                return;
            }
        }
        String uploadFilePath = UploadFileUtil.saveFile(upload);

        Map<String, String> jsonMap = new HashMap<String, String>();
        jsonMap.put(STATUS, SUCCESS);
        jsonMap.put("url", uploadFilePath);
        ajaxJsonErrorMessage("文件大小超出限制!");
    }

    public void appFile(){
        String uploadFileName = "";
        File upload = null;
        UploadFile upfile = getFile();
        if(upfile != null){
            upload = upfile.getFile();
            uploadFileName = upfile.getFileName();
        }
        if(upload == null){
            ajaxJsonErrorMessage("请选择上传文件!");
            return;
        }
        String allowedUploadAppExtension = getSystemConfig().getAllowedUploadAppExtension().toLowerCase();
        if(StringUtils.isEmpty(allowedUploadAppExtension)){
            ajaxJsonErrorMessage("不允许上传文件!");
            return;
        }
        String fileExtension = StringUtils.substringAfterLast(uploadFileName, ".").toLowerCase();
        String[] fileExtensionArray = allowedUploadAppExtension.split(SystemConfig.EXTENSION_SEPARATOR);
        if(!ArrayUtils.contains(fileExtensionArray, fileExtension)){
            ajaxJsonErrorMessage("只允许上传文件类型: " + allowedUploadAppExtension + "!");
            return;
        }
        int uploadLimit = getSystemConfig().getUploadLimit() * 102400;
        if(uploadLimit != 0){
            if(upload != null && upload.length() > uploadLimit){
                ajaxJsonErrorMessage("文件大小超出限制!");
                return;
            }
        }
        String md5Digest = getMd5Digest(upload);
        long size = upload.length();
        Map<String, String> jsonMap = new HashMap<String, String>();
        try{
            final String randomStr = "." + UUID.randomUUID().toString().replace("-", "").substring(0, 10);
            uploadFileName = StringUtils.substringBeforeLast(uploadFileName, ".") + randomStr + "." + fileExtension;
            log.info("uploadFileName=" + uploadFileName);
            UploadResult result = OssUtils.upload(upload, uploadFileName);
            upload.delete();
            log.debug("result=" + result);
            if(result != null && md5Digest.equals(result.digest)){
                jsonMap.put(STATUS, SUCCESS);
                jsonMap.put("url", result.url);
                jsonMap.put("fileName", uploadFileName);
                jsonMap.put("fileSize", String.valueOf(size));
                jsonMap.put("md5", result.digest);
            } else{
                log.error("md5 not equals etag! md5:" + md5Digest + ",eTag=" + result);
                jsonMap.put(STATUS, ERROR);
                jsonMap.put(MESSAGE, VERIFY_FAILED_MSG);
            }
        }
        catch(OSSException | ClientException e){
            e.printStackTrace();
            jsonMap.put(STATUS, ERROR);
            jsonMap.put(MESSAGE, "上传失败，网络错误!");
        }
        renderJson(jsonMap);
    }

    /**
     * @Title: getMd5
     * @Description:TODO
     * @param upload
     *            void
     */

    private String getMd5Digest(File upload){
        String md5 = "";
        try{
            FileInputStream fis = new FileInputStream(upload);

            md5 = DigestUtils.md5Hex(fis).toUpperCase();
            fis.close();
        }
        catch(IOException e){
            e.printStackTrace();
        }
        return md5;
    }
}
